package com.ourteam.frame.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ourteam.frame.web.AbstractSearchHelper;
import com.ourteam.frame.web.AbstractSearchModel;
import com.ourteam.frame.web.GridBean;
import com.ourteam.frame.web.OperationResult;

import net.dao.BaseQueryBean;

public abstract class AbstractCRUDServiceController<Q extends BaseQueryBean, S extends AbstractSearchModel<Q>, DTO>
		extends AbstractServiceController {

	abstract protected Q newQueryBean();

	abstract protected int queryCount(Q queryBean) throws Exception;

	abstract protected DTO[] queryData(Q queryBean) throws Exception;

	abstract protected void deleteData(long[] ids) throws Exception;

	abstract protected DTO getDataById(long id) throws Exception;

	abstract protected void saveData(DTO dataBean) throws Exception;

	@RequestMapping("/query")
	@ResponseBody
	public GridBean query(final @ModelAttribute S searchModel, HttpServletRequest request, Model model)
			throws Exception {

		AbstractSearchHelper<Q, S> searchHelper = new AbstractSearchHelper<Q, S>(searchModel) {

			@Override
			protected Q createQueryBean() {
				return newQueryBean();
			}

			@Override
			protected int queryCount(Q queryBean) throws Exception {
				return AbstractCRUDServiceController.this.queryCount(queryBean);
			}

			@Override
			protected Object[] queryData(Q queryBean) throws Exception {
				return AbstractCRUDServiceController.this.queryData(queryBean);
			}

		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/getById")
	@ResponseBody
	public DTO getById(@RequestParam long id) throws Exception {

		return getDataById(id);
	}

	@RequestMapping("/save")
	@ResponseBody
	public DTO save(@ModelAttribute DTO dataObj) throws Exception {

		saveData(dataObj);

		return dataObj;
	}

	@RequestMapping("/delete")
	@ResponseBody
	public OperationResult delete(@RequestParam long id) throws Exception {

		deleteData(new long[] { id });

		return OperationResult.SUCCESS_RESULT;
	}

	@RequestMapping("/batchDelete")
	@ResponseBody
	public OperationResult delete(@RequestParam long[] ids) throws Exception {

		deleteData(ids);

		return OperationResult.SUCCESS_RESULT;
	}
}
